import dalex as dx
import pandas as pd
import pickle
import xgboost as xgb
import numpy as np
from sklearn.model_selection import train_test_split
input_df = pd.read_csv('data/preprocessed_dataset.csv')
y = input_df.loc[:,'Attrition']
X = input_df.drop('Attrition', axis='columns')
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14)
varaible = ['Total_Trans_Amt','Total_Relationship_Count', 'Months_Inactive_12_mon',
'Contacts_Count_12_mon', 'Total_Revolving_Bal', 'Total_Amt_Chng_Q4_Q1',
'Total_Ct_Chng_Q4_Q1']
xgboost = pickle.load(open("xgb_model.p", "rb" ))
explainer = dx.Explainer(xgboost, X_train, y_train, label='XGB')
Preparation of a new explainer is initiated -> data : 7595 rows 24 cols -> target variable : Parameter 'y' was a pandas.Series. Converted to a numpy.ndarray. -> target variable : 7595 values -> model_class : xgboost.sklearn.XGBClassifier (default) -> label : XGB -> predict function : <function yhat_proba_default at 0x0000024C833C9D30> will be used (default) -> predict function : Accepts pandas.DataFrame and numpy.ndarray. -> predicted values : min = 9.37e-06, mean = 0.841, max = 1.0 -> model type : classification will be used (default) -> residual function : difference between y and yhat (default) -> residuals : min = -0.779, mean = -5.26e-05, max = 0.7 -> model_info : package xgboost A new explainer has been created!
pdp = explainer.model_profile(random_state = 14,variables= varaible)
Calculating ceteris paribus: 100%|███████████████████████████████████████████████████████| 7/7 [00:00<00:00, 21.96it/s]
pdp.plot()
Srednia predykcja dla PDP wynosi 84,2%, że klient nie zrezygnuje.
Jak można się domyślić i z wczęśniejszych analiz zmiany w zmiennej Total_Trans_Amt mają duży wpływ a presydkcję. Dla
Total_Trans_Amt = 0 predykcja, że klient nie zrezygnuje z usługi wynosi 10% a dla kwoty pożywej 11k jest równa prawię 100%. Widoczny wpływ na zmianę predykcji mają także zmienne Contacts_Count_12_mon oraz Total_Ct_Chng_Q4_Q1
ale = explainer.model_profile(type = 'accumulated', random_state = 14, variables= varaible)
Calculating ceteris paribus: 100%|███████████████████████████████████████████████████████| 7/7 [00:00<00:00, 20.60it/s] Calculating accumulated dependency: 100%|████████████████████████████████████████████████| 7/7 [00:00<00:00, 8.41it/s]
ale.plot()
Dla ALE kształty wykresów zmiany predykcji dla wybranych zmiennych wyglądją podobnie. Dla Total_Trans_Amt predykcja w najwyższych punktach jest większa niż 1 i osiąga do 150%, a w najniższym punkcie wynosi ok. 68%. Tylko Total_Trans_Amt i Contacts_Count_12_mon osiąga przedykcję mniejszą niż 50%.
pdp = explainer.model_profile(type = 'partial', random_state=14, variables= varaible)
ale.result['_label_'] = "ALE"
pdp.result['_label_'] = "PDP"
Calculating ceteris paribus: 100%|███████████████████████████████████████████████████████| 7/7 [00:00<00:00, 24.24it/s]
ale.plot(pdp)
Wykresy dla PDP i ALE nie zmieniły kształu. Dla zmienncyh które mają większy wpływ na zmiany w predykcji jak: Total_Ct_Chng_Q4_Q1 i Total_Trans_Amt(oprócz Contacts_Count_12_mon) wykresy ALE znajdują się nad wykresami PDP, osiągając wyższą predykcję. Dla pozostałych zmiennych jest na odwrót. Pozostałe zmienne które w wyjaśnieniach lokalnych miały duży wplyw dla niektóreych obserwacji, według PDP i ALE mają mały wpływ na predykcję.